#include "../include/taskQueue.h"
#include <thread>
#include <iostream>

using std::cout;

TaskQueue::TaskQueue(size_t capacity)
:_capacity(capacity)
,_queue()
,_mutex()
,_notEmpty()
,_notFull()
,_endFlag(false)
{

}

TaskQueue::~TaskQueue()
{

}

void TaskQueue::push(function<void()> && pTask)
{
	unique_lock<mutex> ul(_mutex);
	// 判断是否为满，并避免虚假唤醒
	while(full())
	{
		cout << "任务已满，请稍后添加\n";
		_notFull.wait(ul);
	}
	// 不满则放入队列
	_queue.push(pTask);
	// 告知一个消费者队列不空了
	_notEmpty.notify_one();
	cout << "添加任务，当前任务数量：" << _queue.size() << "\n";
}

function<void()> TaskQueue::pop()
{
	unique_lock<mutex> ul(_mutex);
	
	while(empty() && !_endFlag)
	{
		cout << "任务已空，请稍后\n";
		_notEmpty.wait(ul);
	}
	// 检测是否主线程是否准备退出
	if(!_endFlag)
	{
		auto popTask = _queue.front();
   		_queue.pop();

   		_notFull.notify_one();

		cout << std::this_thread::get_id() << " 拿出任务，当前任务数量：" << _queue.size() << "\n";
   		return popTask; 
	}
	else
	{
		cout << "收到主线程退出请求\n";
		return NULL;
	}
}

bool TaskQueue::empty() const
{
	return _queue.size() == 0;
}

bool TaskQueue::full() const
{
	return _queue.size() == _capacity;
}

void TaskQueue::wakeUp()
{
	cout << "正在的通知所有阻塞线程退出\n";
	// 调用该函数，说明主线程准备退出了
	_endFlag = true;
	_notEmpty.notify_all();
}


